package com.tanker.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;

import net.sf.json.JSONObject;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;

public class HttpClientUtil {

	private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);

	public static String doGet(String url) {
		return doGet(url, null);
	}
//com.tanker.common.utils.microRental
	public static String doGet(String url, Map<String, String> param) {
		
		CloseableHttpClient httpclient = HttpClients.createDefault();

		String result = "";
		CloseableHttpResponse response = null;
		try {
		
			URIBuilder builder = new URIBuilder(url);
			if (param != null) {
				for (String key : param.keySet()) {
					builder.addParameter(key, param.get(key));
				}
			}
			URI uri = builder.build();

			HttpGet httpGet = new HttpGet(uri);

			response = httpclient.execute(httpGet);

			if (response.getStatusLine().getStatusCode() == 200) {
				result = EntityUtils.toString(response.getEntity(),
						"UTF-8");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (response != null) {
					response.close();
				}
				httpclient.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	public static String doPost(String url, Map<String, String> params) {  
		String charset = "utf-8";
        StringBuffer response = new StringBuffer();  
        HttpClient client = new HttpClient();  
        PostMethod method = new PostMethod(url);  
        // 设置Http Post数据  
        method.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=" + charset);  
        if(params != null){  
            Set<String> keySet = params.keySet();  
            NameValuePair[] param = new NameValuePair[keySet.size()];  
            int i = 0;  
            for(String key : keySet){  
                param[i] = new NameValuePair(key, params.get(key));  
                i++;  
            }  
            method.setRequestBody(param);  
        }  
        InputStream responseBodyStream = null;  
        InputStreamReader streamReader = null;  
        BufferedReader reader = null;  
        try {  
            client.executeMethod(method);  
            if (method.getStatusCode() == HttpStatus.SC_OK) {  
                responseBodyStream = method.getResponseBodyAsStream();  
                streamReader = new InputStreamReader(responseBodyStream, charset);  
                reader = new BufferedReader(streamReader);  
                String line;  
                while ((line = reader.readLine()) != null) {  
                    response.append(line);  
                }  
            } else {
				
            	logger.info("code={}",method.getStatusCode());  
			} 
        } catch (IOException e) {  
        	logger.error("执行HTTP Post请求" + url + "时，发生异常！", e);  
        } finally {  
            try {  
            	if (responseBodyStream!=null) {
            		responseBodyStream.close();  
				}
            	if (streamReader!=null) {
            		streamReader.close();  
            	}
            	if (reader!=null) {
            		reader.close();  
            	}
            } catch (IOException e) {  
            	logger.error("执行HTTP Post请求" + url + "时，发生异常，关闭流异常！", e);  
                e.printStackTrace();  
            }  
            method.releaseConnection();  
        }  
        return response.toString();  
    }

	public static String doPostJson(String url, String json) {
		CloseableHttpClient httpClient = HttpClients.createDefault();
		CloseableHttpResponse response = null;
		String result = "";
		try {
			HttpPost httpPost = new HttpPost(url);
			StringEntity entity = new StringEntity(json,
					ContentType.APPLICATION_JSON);
			httpPost.setEntity(entity);
			response = httpClient.execute(httpPost);
			result = EntityUtils.toString(response.getEntity(), "utf-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				response.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		return result;
	}
	/**
	 * 获取
	 * @param url
	 * @param param
	 * @return
	 */
	public static String doPostNew(String url, Map<String, Object> params) {
		String charset = "utf-8";
        StringBuffer response = new StringBuffer();  
        HttpClient client = new HttpClient();  
        PostMethod method = new PostMethod(url);  
        // 设置Http Post数据  
        method.setRequestHeader("Content-Type","application/json;charset=" + charset);  
        //method.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=" + charset);  
        if(params != null){  
            Set<String> keySet = params.keySet();  
            NameValuePair[] param = new NameValuePair[keySet.size()];  
            int i = 0;  
            for(String key : keySet){  
                param[i] = new NameValuePair(key, params.get(key).toString());  
                i++;  
            }  
            method.setRequestBody(param);  
        }  
        InputStream responseBodyStream = null;  
        InputStreamReader streamReader = null;  
        BufferedReader reader = null;  
        try {  
            client.executeMethod(method); 
            
            if (method.getStatusCode() == HttpStatus.SC_OK) {  
                responseBodyStream = method.getResponseBodyAsStream();  
                streamReader = new InputStreamReader(responseBodyStream, charset);  
                reader = new BufferedReader(streamReader);  
                String line;  
                while ((line = reader.readLine()) != null) {  
                    response.append(line);  
                }  
            } else {
				logger.info("返回结果code={},method={}",method.getStatusCode(),method);
			}
            
        } catch (IOException e) {  
        	e.printStackTrace();
        	logger.error("执行HTTP Post请求" + url + "时，发生异常！", e);  
        } finally {  
            try {  
            	if (responseBodyStream!=null) {
            		responseBodyStream.close();  
				}
            	if (streamReader!=null) {
            		streamReader.close();  
            	}
            	if (reader!=null) {
            		reader.close();  
            	}
            } catch (IOException e) {  
            	logger.error("执行HTTP Post请求" + url + "时，发生异常，关闭流异常！", e);  
                e.printStackTrace();  
            }  
            method.releaseConnection();  
        }  
        return response.toString();  
	}
	 public static String http(String url, Map<String, Object> params, String userAgent) {  
	        URL u = null;  
	        HttpURLConnection con = null;  
	        // 构建请求参数  
	        StringBuffer sb = new StringBuffer();  
	        try {
		        if (params != null) {  
		            for (Entry<String, Object> e : params.entrySet()) {  
		            	sb.append(e.getKey());
		            	sb.append("=");
		            	if(e.getValue()==null)
		            	{
		            		sb.append(URLEncoder.encode("","UTF-8"));
		            	}
		            	else
		            	{
		            		sb.append(URLEncoder.encode(e.getValue().toString(),"UTF-8"));
		            	}
		                sb.append("&");  
		            }  
		            sb.substring(0, sb.length() - 1);  
		        }  
		        System.out.println("send_url:" + url);  
		        System.out.println("send_data:" + sb.toString());  
		        // 尝试发送请求  
		        u = new URL(url);  
		        con = (HttpURLConnection) u.openConnection();  
		        //// POST 只能为大写，严格限制，post会不识别  
		        con.setRequestMethod("POST");  
		        con.setDoOutput(true);  
		        con.setDoInput(true);  
		        con.setUseCaches(false);  
		        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");  
		        con.setRequestProperty("user-agent",userAgent);
		        OutputStreamWriter osw = new OutputStreamWriter(con.getOutputStream(), "UTF-8");  
		        osw.write(sb.toString());  
		        osw.flush();  
		        osw.close();  
	        } catch (Exception e) {  
	        	logger.error("发送http请求异常--->>调用后结果,参数:{},访问地址:{}",params,url);
	        	logger.error("异常信息",e);
	            e.printStackTrace();  
	        } finally {  
	            if (con != null) {  
	                con.disconnect();  
	            }  
	        }  
	  
	        // 读取返回内容  
	        StringBuffer buffer = new StringBuffer();  
	        try {  
	            //一定要有返回值，否则无法把请求发送给server端。  
	            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "UTF-8"));  
	            String temp;  
	            while ((temp = br.readLine()) != null) {  
	                buffer.append(temp);  
	                buffer.append("\n");  
	            }  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	        }  
	  
	        return buffer.toString();  
	    } 
	 
	//设置链接超时和请求超时等参数，否则会长期停止或者崩溃
	 private static RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60000).setConnectTimeout(60000).setConnectionRequestTimeout(60000).build();

	 public static String doPosts(String apiUrl, Map<String, Object> params) {  
	        CloseableHttpClient httpClient = HttpClients.createDefault();  
	        String httpStr = null;  
	        HttpPost httpPost = new HttpPost(apiUrl);  
	        CloseableHttpResponse response = null;  
	  
	        try {  
	            httpPost.setConfig(requestConfig);  
	            List<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>(params.size());  
	            for (Map.Entry<String, Object> entry : params.entrySet()) {  
	                BasicNameValuePair pair = new BasicNameValuePair(entry.getKey(), entry  
	                        .getValue().toString());  
	                pairList.add(pair);  
	            }  
	            httpPost.setEntity(new UrlEncodedFormEntity(pairList, Charset.forName("UTF-8")));  
	            response = httpClient.execute(httpPost);  
	            System.out.println(response.toString());  
	            HttpEntity entity = response.getEntity();  
	            httpStr = EntityUtils.toString(entity, "UTF-8");  
	        } catch (IOException e) {  
	            e.printStackTrace();  
	        } finally {  
	            if (response != null) {  
	                try {  
	                    EntityUtils.consume(response.getEntity());  
	                } catch (IOException e) {  
	                    e.printStackTrace();  
	                }  
	            }  
	        }  
	        return httpStr;  
	 } 
	 /*
	 * 获取
	 * @param url
	 * @param param
	 * @return
	 */
	public static String doPostAotu(String url, Map<String, String> params) throws Exception {
		ObjectMapper om = new ObjectMapper();

		String charset = "utf-8";
        StringBuffer response = new StringBuffer();  
        HttpClient client = new HttpClient();  
        PostMethod method = new PostMethod(url);  
        // 设置Http Post数据  
        method.setRequestHeader("Content-Type","application/json;charset=" + charset);  
        //method.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=" + charset);  
        if(params != null){  
            Set<String> keySet = params.keySet();  
            NameValuePair[] param = new NameValuePair[keySet.size()];  
            int i = 0;  
            for(String key : keySet){  
                param[i] = new NameValuePair(key, params.get(key).toString());  
                i++;  
            }  
//            method.setRequestBody(param);  
            method.setRequestBody(om.writeValueAsString(params));  

        }  
        InputStream responseBodyStream = null;  
        InputStreamReader streamReader = null;  
        BufferedReader reader = null;  
        try {  
            client.executeMethod(method); 
            
            if (method.getStatusCode() == HttpStatus.SC_OK) {  
                responseBodyStream = method.getResponseBodyAsStream();  
                streamReader = new InputStreamReader(responseBodyStream, charset);  
                reader = new BufferedReader(streamReader);  
                String line;  
                while ((line = reader.readLine()) != null) {  
                    response.append(line);  
                }  
            } else {
				logger.info("返回结果code={},method={}",method.getStatusCode(),method);
			}
            
        } catch (IOException e) {  
        	e.printStackTrace();
        	logger.error("执行HTTP Post请求" + url + "时，发生异常！", e);  
        } finally {  
            try {  
            	if (responseBodyStream!=null) {
            		responseBodyStream.close();  
				}
            	if (streamReader!=null) {
            		streamReader.close();  
            	}
            	if (reader!=null) {
            		reader.close();  
            	}
            } catch (IOException e) {  
            	logger.error("执行HTTP Post请求" + url + "时，发生异常，关闭流异常！", e);  
                e.printStackTrace();  
            }  
            method.releaseConnection();  
        }  
        return response.toString();  
	} 
	
	/**
	 * 发起https请求并获取结果
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式（GET、POST）
	 * @param outputStr  提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static JSONObject httpsPost(String requestUrl, String outputStr, String requestMethod) {
		//String requestMethod = "POST";
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			httpUrlConn.setRequestProperty("Content-Type", "application/json; charset=utf-8");  
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			logger.error("server connection timed out.");
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return jsonObject;
	}
	
	public static JSONObject httpsPost2(String requestUrl, String outputStr, String requestMethod) {
		//String requestMethod = "POST";
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();

			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			httpUrlConn.setRequestProperty("Content-Type", "multipart/form-data; charset=utf-8"); 
			httpUrlConn.setRequestProperty("accept", "*/*");
			//httpUrlConn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundaryString);
			httpUrlConn.setRequestProperty("connection", "Keep-Alive");
			httpUrlConn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)");
			
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);

			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();

			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}

			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			jsonObject = JSONObject.fromObject(buffer.toString());
		} catch (ConnectException ce) {
			logger.error("server connection timed out.");
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return jsonObject;
	}
	/**
	 * 发起https请求并获取结果
	 * @param requestUrl 请求地址
	 * @param requestMethod 请求方式（GET、POST）
	 * @param outputStr  提交的数据
	 * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
	 */
	public static String httpsPostStr(String requestUrl, String outputStr) {
		String requestMethod = "POST";
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			// 创建SSLContext对象，并使用我们指定的信任管理器初始化
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new java.security.SecureRandom());
			// 从上述SSLContext对象中得到SSLSocketFactory对象
			SSLSocketFactory ssf = sslContext.getSocketFactory();
			
			URL url = new URL(requestUrl);
			HttpsURLConnection httpUrlConn = (HttpsURLConnection) url
					.openConnection();
			httpUrlConn.setSSLSocketFactory(ssf);
			httpUrlConn.setRequestProperty("Content-Type", "application/json; charset=utf-8");  
			httpUrlConn.setDoOutput(true);
			httpUrlConn.setDoInput(true);
			httpUrlConn.setUseCaches(false);
			// 设置请求方式（GET/POST）
			httpUrlConn.setRequestMethod(requestMethod);
			
			if ("GET".equalsIgnoreCase(requestMethod))
				httpUrlConn.connect();
			
			// 当有数据需要提交时
			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();
				// 注意编码格式，防止中文乱码
				outputStream.write(outputStr.getBytes("UTF-8"));
				outputStream.close();
			}
			
			// 将返回的输入流转换成字符串
			InputStream inputStream = httpUrlConn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			BufferedReader bufferedReader = new BufferedReader(
					inputStreamReader);
			
			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				buffer.append(str);
			}
			bufferedReader.close();
			inputStreamReader.close();
			// 释放资源
			inputStream.close();
			inputStream = null;
			httpUrlConn.disconnect();
			return buffer.toString();
		} catch (ConnectException ce) {
			logger.error("server connection timed out.");
		} catch (Exception e) {
			logger.error("https request error:{}", e);
		}
		return null;
	}
}
